package model.data.tableModel.person;

import model.data.interfaces.IFinishable;
import model.data.tableModel.TableControl;
import model.handler.databaseHandling.QueryFactory;

import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;

import enums.Status;

/**
 * Represents the table staff of the database.
 * <p>
 * Stores all data that is required for assistants working at the shop.
 *
 */
public final class Staff implements IFinishable{

	private final static Logger debug = LogManager.getLogger("DEBUG");

	private final int staffID;
	private final String nickname;
	private String salt;
	private String password;
	private Status status;
	private Person person;
	
	private Staff(Person p, String password, String salt, Status staffStatus, int staffID, String nickname) {
		assert nickname != null && !"".equals(nickname);
		assert password != null && !"".equals(password);
		assert salt != null && !"".equals(salt);
		
		this.person = p;
		this.nickname = nickname;
		this.password = password;
		this.salt = salt;
		this.status = staffStatus;
		this.staffID = staffID;
	}
	
	/**
	 * Creates a new object of the class staff.
	 * <p>
	 * Is invoked if a new assistant of the shop should be saved and the data is not already stored in the database.
	 *  
	 * @param firstName
	 * @param lastName
	 * @param room
	 * @param status
	 * @param email
	 * @param password
	 * @param salt
	 * @param staffStatus
	 * @return
	 */
	public static Staff createNewStaff(Person p, String password, String salt, Status staffStatus){
		int id = TableControl.getCentralCounter();
		String nickname = createNickname(p.getFirstName(), p.getLastName(), p.getRoom());
		debug.debug("New Staff created: " + nickname + " ID: " + id);
		return new Staff(p, password, salt, staffStatus, id, nickname);
	}
	
	/**
	 * Creates a new object of the class staff.
	 * <p>
	 * Is invoked if an already existing assistant in the database should be initialized.
	 * 
	 * @param personID
	 * @param firstName
	 * @param lastName
	 * @param room
	 * @param status
	 * @param email
	 * @param password
	 * @param salt
	 * @param staffStatus
	 * @param staffID 
	 * @return
	 */
	public static Staff createExistingStaff(int staffID, Person p, String password, String salt, Status staffStatus, String nickname){
		debug.debug("Existing Staff created: " + nickname + " ID: " + staffID);
		return new Staff(p, password, salt, staffStatus, staffID, nickname);
	}
	
	@Override
	public String toString(){
		return nickname;
	}

	@Override
	public boolean writeToDB() {
		boolean ret = false;

		ret = QueryFactory.writeStaffToDB(false, nickname, password, salt, person.getPersonID(), status, staffID);		
		return ret;
	}
	
	@Override
	public boolean writeUpdateToDB() {
		boolean ret = false;
		
		ret = QueryFactory.writeStaffToDB(true, nickname, password, salt, person.getPersonID(), status, staffID);
		return ret;
	}

	public static String createNickname(String firstName, String lastName, int room) {
		String str = lastName + firstName.charAt(0) + room;
		return str;
	}
	
	/* GETTER AND SETTER BELOW */

	public String getNickname() {
		return nickname;
	}

	public String getPassword() {
		return password;
	}

	public String getSalt() {
		return salt;
	}

	public Status getStatus() {
		return status;
	}

	@Override
	public void setStatus(Status status) {
		this.status = status;
	}

	public Integer getStaffID() {
		return staffID;
	}

	public boolean setPassword(String newPw, String newSalt) {
		this.password = newPw;
		this.salt = newSalt;
		debug.debug("New password set for: " + this);
		return this.writeUpdateToDB();
	}
	
	public Person getPerson(){
		return person;
	}
}
